﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.ExportToRTR.CUiExportToRTRContentDataHandler
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.ExportToRTR.Resources;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Threading;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Olp;
using UiInternalControls.WindowsFormsControls;

namespace DnProcessSimulateCommands.ExportToRTR
{
    public class CUiExportToRTRContentDataHandler
    {
        private const string REGISTRY_VALUE_CONNECTION_WIZARD_TYPE_NONE = "None";
        private const string REGISTRY_VALUE_CONNECTION_WIZARD_TYPE_TWO_WAYS = "ApproachAndRetract";
        private const string REGISTRY_VALUE_CONNECTION_WIZARD_TYPE_ONE_WAY = "Approach";
        private const string REGISTRY_VALUE_CONNECTION_WIZARD_KEY = "LocationRoadmapWizardMode";
        private const string REGISTRY_VALUE_COMPUTE_COLLISION_SETS_KEY = "IncludeCollisionRules";
        private Dictionary<ITxDevice, TxPoseData> _collisionCheckInitialDevicePoses;
        private bool _isValidationModified;
        internal Dispatcher _dispatcher;
        internal Dictionary<ITxRobot, CApExportToRTRRobotCollisionSetsData> CollisionSetsData = new Dictionary<ITxRobot, CApExportToRTRRobotCollisionSetsData>();
        internal TxObjectList _selectedObjects = new TxObjectList();
        internal HashSet<ITxRoboticLocationOperation> _selectedLocations = new HashSet<ITxRoboticLocationOperation>();

        internal CUiExportToRTRContentDataHandler.ConnectionWizardType LocationsConnectionTypeForWizard { get; set; } = CUiExportToRTRContentDataHandler.ConnectionWizardType.Approach;

        internal bool InCreation { get; set; } = true;

        internal HashSet<ITxRoboticLocationOperation> UnReachableLocations { get; set; } = new HashSet<ITxRoboticLocationOperation>();

        internal HashSet<ITxRoboticLocationOperation> UnConfiguredLocations { get; set; } = new HashSet<ITxRoboticLocationOperation>();

        internal HashSet<ITxRoboticLocationOperation> CollidingLocations { get; set; } = new HashSet<ITxRoboticLocationOperation>();

        internal Dictionary<ITxRoboticLocationOperation, CApExportToRTRLocationData> DataOfLocations { get; set; } = new Dictionary<ITxRoboticLocationOperation, CApExportToRTRLocationData>();

        internal Dictionary<ITxRobot, CApExportToRTRRobotData> DataOfRobots { get; set; } = new Dictionary<ITxRobot, CApExportToRTRRobotData>();

        internal Dictionary<ITxDevice, CApExportToRTRRobotToolData> DataOfTools { get; set; } = new Dictionary<ITxDevice, CApExportToRTRRobotToolData>();

        internal Dictionary<ITxRoboticOrderedCompoundOperation, CApExportToRTROperationData> DataOfOperation { get; set; } = new Dictionary<ITxRoboticOrderedCompoundOperation, CApExportToRTROperationData>();

        internal CApExportToRTR3DData RTR3DData { get; set; } = new CApExportToRTR3DData();

        public CUiExportToRTRProgressHandler ProgressHandler { get; set; }

        internal int SegmentTime { get; set; }

        public TxObjectList SelectedObjects => this._selectedObjects;

        public HashSet<ITxRoboticLocationOperation> SelectedLocations => this._selectedLocations;

        internal CApExportToRTRStatusManager StatusManager { get; set; }

        internal Action RefreshStatus { get; set; }

        internal bool IsValidationModified
        {
            get
            {
                bool validationModified = this._isValidationModified;
                this._isValidationModified = false;
                return validationModified;
            }
        }

        internal Dispatcher CurrentDispatcher
        {
            set => this._dispatcher = value;
        }

        internal bool ComputeCollisionSets { get; } = true;

        internal CUiExportToRTRContentDataHandler()
        {
            string str1 = CApExportToRTRUtils.ReadValueFromRegistry("LocationRoadmapWizardMode");
            if (!string.IsNullOrEmpty(str1))
            {
                switch (str1)
                {
                    case "ApproachAndRetract":
                        this.LocationsConnectionTypeForWizard = CUiExportToRTRContentDataHandler.ConnectionWizardType.ApproachAndRetract;
                        break;
                    case "Approach":
                        this.LocationsConnectionTypeForWizard = CUiExportToRTRContentDataHandler.ConnectionWizardType.Approach;
                        break;
                }
            }
            string str2 = CApExportToRTRUtils.ReadValueFromRegistry("IncludeCollisionRules");
            if (string.IsNullOrEmpty(str2) || !(str2 == "False"))
                return;
            this.ComputeCollisionSets = false;
        }

        internal static TxObjectList ComputeOperationsFromSelection<T>(TxObjectList selection)
        {
            HashSet<ITxObject> txObjectSet = new HashSet<ITxObject>();
            foreach (ITxObject operation1 in (Collection<ITxObject>)selection)
            {
                if (CUiExportToRTRContentViewModel.AllowedOpertionType(operation1))
                {
                    if (operation1 is T)
                        txObjectSet.Add(operation1);
                    else if (operation1 is ITxCompoundOperation compoundOperation)
                    {
                        TxObjectList allDescendants = compoundOperation.GetAllDescendants((ITxTypeFilter)new TxTypeFilter(typeof(T)));
                        if (allDescendants != null)
                        {
                            foreach (ITxObject operation2 in (Collection<ITxObject>)allDescendants)
                            {
                                if (CUiExportToRTRContentViewModel.AllowedOpertionType(operation2))
                                    txObjectSet.Add(operation2);
                            }
                        }
                    }
                }
            }
            TxObjectList operationsFromSelection = new TxObjectList();
            foreach (ITxObject txObject in txObjectSet)
                operationsFromSelection.Add(txObject);
            return operationsFromSelection;
        }

        internal void UpdateLocationsList(
          TxObjectList selectedObjects,
          Action<double, double, string> startProgress,
          Action resetProgress)
        {
            HashSet<ITxRoboticLocationOperation> nonHandledlocations = new HashSet<ITxRoboticLocationOperation>((IEnumerable<ITxRoboticLocationOperation>)this.SelectedLocations);
            Dictionary<ITxRobot, List<ITxRoboticLocationOperation>> robotToLocationsMap = new Dictionary<ITxRobot, List<ITxRoboticLocationOperation>>();
            double num = 0.0;
            bool areThereInitalOperations = this.SelectedLocations.Count != 0;
            this.StartAddLocations();
            this.SortLocationsByRobots(selectedObjects, robotToLocationsMap, nonHandledlocations);
            this.ApplyLocationConnection(selectedObjects);
            foreach (KeyValuePair<ITxRobot, List<ITxRoboticLocationOperation>> keyValuePair in robotToLocationsMap)
            {
                ITxRobot robot = keyValuePair.Key;
                List<ITxRoboticLocationOperation> locationOperationList = keyValuePair.Value;
                this.CheckInitializeDevicePoses();
                ++num;
                foreach (ITxRoboticLocationOperation locationOperation in locationOperationList)
                {
                    ITxRoboticLocationOperation location = locationOperation;
                    this._dispatcher.BeginInvoke((Action)(() =>
                    {
                        this.CheckSelectedLocation(location, robot);
                        this.ProgressHandler.Increment();
                    }), DispatcherPriority.Background);
                    ++num;
                }
                this.CheckRestoreDevicePoses();
                ++num;
            }
            this._dispatcher.BeginInvoke((Action)(() =>
            {
                Action refreshStatus = this.RefreshStatus;
                if (refreshStatus != null)
                    refreshStatus();
                bool flag = this.SelectedLocations.Count != 0;
                if (!areThereInitalOperations && !flag)
                    this._isValidationModified = true;
                if (flag != areThereInitalOperations)
                {
                    this._isValidationModified = true;
                }
                else
                {
                    if (!(this.InCreation & flag))
                        return;
                    this._isValidationModified = true;
                }
            }), DispatcherPriority.Background);
            this.EndAddLocations();
            startProgress(num, 1.0, ExportToRTRStringTable.STATUS_BAR_SET_LOCATIONS);
            if (this.InCreation)
                return;
            this._dispatcher.BeginInvoke((Action)(() => resetProgress()), DispatcherPriority.Background);
        }

        internal void RemoveOperationLocations(TxObjectList operationsToRemove)
        {
            TxObjectList operationsFromSelection = CUiExportToRTRContentDataHandler.ComputeOperationsFromSelection<ITxRoboticLocationOperation>(operationsToRemove);
            foreach (ITxObject location in (Collection<ITxObject>)operationsFromSelection)
                this.RemoveLocation(location as ITxRoboticLocationOperation);
            if (operationsFromSelection.Count <= 0)
                return;
            this._isValidationModified = true;
        }

        private void SortLocationsByRobots(
          TxObjectList selectedObjects,
          Dictionary<ITxRobot, List<ITxRoboticLocationOperation>> robotToLocationsMap,
          HashSet<ITxRoboticLocationOperation> nonHandledlocations)
        {
            foreach (ITxObject selectedObject in (Collection<ITxObject>)selectedObjects)
            {
                if (selectedObject is ITxRoboticLocationOperation location)
                    this.AddLocationToRobotMap(location, robotToLocationsMap, nonHandledlocations);
                else if (selectedObject is ITxObjectCollection objectCollection)
                {
                    foreach (ITxRoboticLocationOperation allDescendant in (Collection<ITxObject>)objectCollection.GetAllDescendants((ITxTypeFilter)new TxTypeFilter(typeof(ITxRoboticLocationOperation))))
                    {
                        if (allDescendant != null && CUiExportToRTRContentViewModel.AllowedOpertionType((ITxObject)allDescendant.Collection))
                            this.AddLocationToRobotMap(allDescendant, robotToLocationsMap, nonHandledlocations);
                    }
                }
            }
        }

        private void AddLocationToRobotMap(
          ITxRoboticLocationOperation location,
          Dictionary<ITxRobot, List<ITxRoboticLocationOperation>> robotToLocationsMap,
          HashSet<ITxRoboticLocationOperation> nonHandledlocations)
        {
            if (this.SelectedLocations.Contains(location))
            {
                nonHandledlocations.Remove(location);
            }
            else
            {
                this.SelectedLocations.Add(location);
                ITxRobot txRobot = CApExportToRTRUtils.AssignedRobot(location);
                ITxRoboticOrderedCompoundOperation roboticOperation = location.ParentRoboticOperation;
                CApExportToRTROperationData rtrOperationData = (CApExportToRTROperationData)null;
                if (roboticOperation != null)
                    rtrOperationData = this.ComputeOperationData(roboticOperation);
                if (rtrOperationData != null && rtrOperationData.LocationsCount == 0)
                {
                    if (txRobot != null)
                        this.ComputeRobotData(txRobot).SimulatingOperations.Add((ITxOperation)roboticOperation);
                    else
                        this.StatusManager.AddIssue(CApExportToRTRStatusManager.IssueType.NoSimulatedRobot, (ITxObject)roboticOperation);
                }
                if (rtrOperationData != null)
                    ++rtrOperationData.LocationsCount;
                if (txRobot == null)
                    return;
                if (!robotToLocationsMap.ContainsKey(txRobot))
                    robotToLocationsMap.Add(txRobot, new List<ITxRoboticLocationOperation>());
                robotToLocationsMap[txRobot].Add(location);
            }
        }

        internal void ApplyLocationConnection(TxObjectList selectedObjects)
        {
            if (this.LocationsConnectionTypeForWizard == CUiExportToRTRContentDataHandler.ConnectionWizardType.None)
                return;
            foreach (ITxObject selectedObject in (Collection<ITxObject>)selectedObjects)
            {
                if (selectedObject is ITxRoboticOrderedCompoundOperation roboticOperation)
                    this.ApplyLocationConnectionOnRoboticOperation(roboticOperation);
                else if (selectedObject is ITxObjectCollection objectCollection)
                {
                    foreach (ITxRoboticOrderedCompoundOperation allDescendant in (Collection<ITxObject>)objectCollection.GetAllDescendants((ITxTypeFilter)new TxTypeFilter(typeof(ITxRoboticOrderedCompoundOperation))))
                        this.ApplyLocationConnectionOnRoboticOperation(allDescendant);
                }
            }
        }

        private void ApplyLocationConnectionOnRoboticOperation(
          ITxRoboticOrderedCompoundOperation roboticOperation)
        {
            ITxOrderedObjectCollection objectCollection = (ITxOrderedObjectCollection)roboticOperation;
            int num1 = objectCollection.Count - 1;
            int num2 = 0;
            ITxRoboticLocationOperation locationOperation = (ITxRoboticLocationOperation)null;
            for (int index = num1; index >= num2; --index)
            {
                ITxRoboticLocationOperation childAt = objectCollection.GetChildAt(index) as ITxRoboticLocationOperation;
                CApExportToRTRLocationData locationData = this.ComputeLocationData(childAt);
                if (locationOperation != null)
                    locationData.NextLocation = locationOperation;
                locationOperation = childAt;
            }
        }

        private void CheckSelectedLocation(ITxRoboticLocationOperation location, ITxRobot robot)
        {
            CApExportToRTRLocationData locationData = this.ComputeLocationData(location);
            TxRobotConfigurationData configurationData = location.RobotConfigurationData;
            if (configurationData == null)
            {
                this.UnConfiguredLocations.Add(location);
                this._isValidationModified = true;
            }
            else
                locationData.Configuration = configurationData;
            TxPoseData location1 = this.UpdateCurrentPoseData(location) ? this.JumpToLocation(location, robot) : (TxPoseData)null;
            if (location1 == null)
            {
                this.UnReachableLocations.Add(location);
                this._isValidationModified = true;
            }
            else
            {
                locationData.RobotPose = location1;
                this.CheckCollidingGun(location);
            }
        }

        private void RemoveLocation(ITxRoboticLocationOperation location)
        {
            this.SelectedLocations.Remove(location);
            this.RemoveLocationFromSet(this.UnConfiguredLocations, location);
            this.RemoveLocationFromSet(this.UnReachableLocations, location);
            this.RemoveLocationFromSet(this.CollidingLocations, location);
            this.DataOfLocations.Remove(location);
            this.StatusManager?.RemoveObjectFromIssues((ITxObject)location);
            ITxRoboticOrderedCompoundOperation roboticOperation = location.ParentRoboticOperation;
            CApExportToRTROperationData operationData = this.ComputeOperationData(roboticOperation);
            if (operationData == null)
                return;
            --operationData.LocationsCount;
            if (operationData.LocationsCount != 0)
                return;
            if (roboticOperation.Robot != null)
                this.ComputeRobotData(roboticOperation.Robot).SimulatingOperations.Remove((ITxOperation)roboticOperation);
            this.StatusManager?.RemoveObjectFromIssues((ITxObject)roboticOperation);
        }

        internal CApExportToRTRLocationData ComputeLocationData(
          ITxRoboticLocationOperation currentLocationOperation)
        {
            CApExportToRTRLocationData locationData = (CApExportToRTRLocationData)null;
            if (!this.DataOfLocations.TryGetValue(currentLocationOperation, out locationData))
            {
                locationData = new CApExportToRTRLocationData();
                this.DataOfLocations.Add(currentLocationOperation, locationData);
            }
            return locationData;
        }

        internal CApExportToRTROperationData ComputeOperationData(
          ITxRoboticOrderedCompoundOperation currentOperation)
        {
            CApExportToRTROperationData operationData = (CApExportToRTROperationData)null;
            if (!this.DataOfOperation.TryGetValue(currentOperation, out operationData))
            {
                operationData = new CApExportToRTROperationData();
                this.DataOfOperation.Add(currentOperation, operationData);
            }
            return operationData;
        }

        private void RemoveLocationFromSet(
          HashSet<ITxRoboticLocationOperation> locationsSet,
          ITxRoboticLocationOperation location)
        {
            if (!locationsSet.Remove(location))
                return;
            this._isValidationModified = true;
        }

        private void StartAddLocations()
        {
            this._dispatcher.BeginInvoke((Action)(() =>
            {
                TxApplicationEx.FreezeDisplay();
                this.ProgressHandler.Increment();
            }), DispatcherPriority.Background);
        }

        private void EndAddLocations()
        {
            this._dispatcher.BeginInvoke((Action)(() => TxApplicationEx.UnfreezeDisplay()), DispatcherPriority.Background);
        }

        private void CheckInitializeDevicePoses()
        {
            this._dispatcher.BeginInvoke((Action)(() =>
            {
                this._collisionCheckInitialDevicePoses = new Dictionary<ITxDevice, TxPoseData>();
                this.ProgressHandler.Increment();
            }), DispatcherPriority.Background);
        }

        private TxPoseData JumpToLocation(ITxRoboticLocationOperation location, ITxRobot robot)
        {
            TxPoseData location1 = (TxPoseData)null;
            ITxRoboticOperation operation = (ITxRoboticOperation)location.ParentRoboticOperation ?? (ITxRoboticOperation)null;
            if (operation != null)
            {
                robot = (ITxRobot)new TxOlpControllerUtilities().GetRobot((ITxOperation)operation);
                if (robot != null)
                {
                    ITxRoboticControllerServices controllerServices = CApExportToRTRUtils.GetRoboticControllerServices(robot as TxRobot);
                    if (controllerServices != null)
                    {
                        if (controllerServices.JumpToLocation((ITxLocationOperation)location, new TxJumpToLocationData()
                        {
                            ForceConfiguration = false,
                            UseWorkToolAndSystemFrames = true,
                            UseTaughtLocations = true,
                            UseTaughtPose = true,
                            GenerateMessage = false
                        }) == TxJumpToLocationStatus.Success)
                            location1 = (robot as ITxDevice).CurrentPose;
                    }
                }
            }
            return location1;
        }

        private CApExportToRTRRobotData ComputeRobotData(ITxRobot robot)
        {
            CApExportToRTRRobotData robotData = (CApExportToRTRRobotData)null;
            if (!this.DataOfRobots.TryGetValue(robot, out robotData))
            {
                robotData = new CApExportToRTRRobotData();
                this.UpdateRobotData(robot, robotData);
                this.DataOfRobots.Add(robot, robotData);
            }
            return robotData;
        }

        private bool CheckCollidingGun(ITxRoboticLocationOperation location)
        {
            ITxWeldOperation roboticOperation = location.ParentRoboticOperation as ITxWeldOperation;
            bool flag = false;
            if (roboticOperation != null)
            {
                TxCollisionRoot collisionRoot = TxApplication.ActiveDocument.CollisionRoot;
                using (TxCollisionQueryParams queryParams = new TxCollisionQueryParams()
                {
                    Mode = TxCollisionQueryParams.TxCollisionQueryMode.DefinedPairs,
                    UseNearMiss = true,
                    NearMissDistance = TxApplication.Options.Collision.CheckNearMiss ? collisionRoot.NearMissDefaultValue : 0.1
                })
                {
                    using (TxCollisionQueryResults collidingObjects = TxApplication.ActiveDocument.CollisionRoot.GetCollidingObjects(queryParams))
                    {
                        if (collidingObjects.States.Count > 0)
                        {
                            this.CollidingLocations.Add(location);
                            this._isValidationModified = true;
                            flag = true;
                        }
                    }
                }
            }
            return flag;
        }

        private void CheckRestoreDevicePoses()
        {
            this._dispatcher.BeginInvoke((Action)(() =>
            {
                foreach (KeyValuePair<ITxDevice, TxPoseData> initialDevicePose in this._collisionCheckInitialDevicePoses)
                {
                    initialDevicePose.Key.CurrentPose = initialDevicePose.Value;
                    this.ProgressHandler.Increment();
                }
            }), DispatcherPriority.Background);
        }

        private bool UpdateCurrentPoseData(ITxRoboticLocationOperation location)
        {
            bool flag = false;
            ITxRoboticOrderedCompoundOperation roboticOperation = location.ParentRoboticOperation;
            if (roboticOperation != null)
            {
                ITxRobot robot = roboticOperation.Robot;
                if (robot != null && this.UpdateCurrentPoseDataWithDevice(robot as ITxDevice))
                {
                    flag = true;
                    this.UpdateCurrentPoseDataForAxis(location.RobotExternalAxesData);
                }
            }
            return flag;
        }

        private void UpdateCurrentPoseDataForAxis(TxRobotExternalAxisData[] axisDataList)
        {
            if (axisDataList == null || axisDataList.Length == 0)
                return;
            foreach (TxRobotExternalAxisData axisData in axisDataList)
                this.UpdateCurrentPoseDataWithDevice(axisData.Device);
        }

        private bool UpdateCurrentPoseDataWithDevice(ITxDevice device)
        {
            bool flag = true;
            if (device != null)
            {
                if (!this._collisionCheckInitialDevicePoses.ContainsKey(device))
                {
                    TxPoseData currentPose = device.CurrentPose;
                    if (currentPose == null)
                        flag = false;
                    else
                        this._collisionCheckInitialDevicePoses.Add(device, currentPose);
                }
            }
            else
                flag = false;
            return flag;
        }

        private void UpdateRobotData(ITxRobot robot, CApExportToRTRRobotData robotData)
        {
            if (CApExportToRTRUtils.IsVisibleAndHaveApprox(robot as ITxDisplayableObject))
            {
                robotData.Is7Axis = (robot as TxRobot).DrivingJoints.Count > 6;
                if (robotData.Is7Axis)
                    this._isValidationModified = true;
                this.UpdateRobotExternalAxes(robot, robotData);
                this.UpdateRobotMountedWorpieces(robot, robotData);
                this.UpdateRobotExternalAxesDevices(robot, robotData);
            }
            else
            {
                robotData.IsVisible = false;
                this._isValidationModified = true;
            }
        }

        private void UpdateRobotExternalAxes(ITxRobot robot, CApExportToRTRRobotData robotData)
        {
            foreach (ITxObject externalAx in (Collection<ITxObject>)robot.ExternalAxes)
            {
                TxJoint txJoint = externalAx as TxJoint;
                if (txJoint != (ITxObject)null)
                {
                    ITxDevice device = txJoint.Device;
                    if (device != null)
                        robotData.ExternalAxes.Add(device);
                }
            }
        }

        private void UpdateRobotMountedWorpieces(ITxRobot robot, CApExportToRTRRobotData robotData)
        {
            robotData.MountedWorkpieces = robot.MountedTools;
            if (robotData.MountedWorkpieces == null)
                return;
            foreach (ITxObject mountedWorkpiece in (Collection<ITxObject>)robotData.MountedWorkpieces)
            {
                if (mountedWorkpiece is ITxDevice device && CApExportToRTRUtils.IsVisibleAndHaveApprox(device as ITxDisplayableObject))
                    this.UpdateRobotToolData(device, robotData, robot);
            }
        }

        private void UpdateRobotToolData(
          ITxDevice device,
          CApExportToRTRRobotData robotData,
          ITxRobot robot)
        {
            CApExportToRTRRobotToolData rtrRobotToolData = new CApExportToRTRRobotToolData();
            this.UpdateDeviceExternalAxes(device, robotData, rtrRobotToolData);
            this.UpdateDeviceGun(device, rtrRobotToolData);
            this.UpdateDeviceGunWithCompensationJoint(device, robot, rtrRobotToolData);
            this.UpdateDeviceGunWithOtherExternal(device, robot, rtrRobotToolData);
            this.UpdateDeviceRail(device, robot, rtrRobotToolData);
            this.DataOfTools.Add(device, rtrRobotToolData);
        }

        private void UpdateDeviceRail(
          ITxDevice device,
          ITxRobot robot,
          CApExportToRTRRobotToolData toolData)
        {
            bool flag = false;
            if (toolData.IsExternalAxis && !toolData.IsServoGun)
            {
                ITxObject joint = robot.ExternalAxes.ToList<ITxObject>().Find((Predicate<ITxObject>)(x => (x as TxJoint).Device == device));
                flag = CApExportToRTRUtils.IsJointOfRail(robot, joint as TxJoint);
            }
            if (!flag)
                return;
            this._isValidationModified = toolData.IsRail = true;
        }

        private void UpdateDeviceExternalAxes(
          ITxDevice device,
          CApExportToRTRRobotData robotData,
          CApExportToRTRRobotToolData mountedToolData)
        {
            if (robotData.ExternalAxes.Contains(device))
                mountedToolData.IsExternalAxis = true;
            else
                this._isValidationModified = true;
        }

        private void UpdateDeviceGun(ITxDevice device, CApExportToRTRRobotToolData mountedToolData)
        {
            this.UpdateDeviceServoGun(device, mountedToolData);
            if (!mountedToolData.IsServoGun)
                return;
            this.UpdateDeviceGunWithLoops(device, mountedToolData);
            this.UpdateDeviceGunWithAvailableKinemtaicFunctions(device, mountedToolData);
            this.UpdateDeviceGunWithSoftLimits(device, mountedToolData);
        }

        private void UpdateDeviceGunWithCompensationJoint(
          ITxDevice device,
          ITxRobot robot,
          CApExportToRTRRobotToolData mountedToolData)
        {
            bool flag = false;
            if (mountedToolData.IsExternalAxis && mountedToolData.IsServoGun && robot.ExternalAxes.Count > 1)
                flag = device.DrivingJoints.ToList<ITxObject>().TrueForAll((Predicate<ITxObject>)(x => robot.ExternalAxes.Contains(x))) && device.DrivingJoints.Count > 1;
            if (!flag)
                return;
            this._isValidationModified = mountedToolData.IsGunWithCompensationJoint = true;
        }

        private void UpdateDeviceGunWithOtherExternal(
          ITxDevice device,
          ITxRobot robot,
          CApExportToRTRRobotToolData mountedToolData)
        {
            bool flag = false;
            if (mountedToolData.IsExternalAxis && mountedToolData.IsServoGun && robot.ExternalAxes.Count > 1)
                flag = robot.ExternalAxes.ToList<ITxObject>().Exists((Predicate<ITxObject>)(x => (object)((x as TxJoint).Device as TxServoGun) == null && !CApExportToRTRUtils.IsJointOfRail(robot, x as TxJoint)));
            if (!flag)
                return;
            this._isValidationModified = mountedToolData.HasExternalNonGun = true;
        }

        private void UpdateDeviceServoGun(ITxDevice device, CApExportToRTRRobotToolData mountedToolData)
        {
            if ((object)(device as TxServoGun) != null)
                mountedToolData.IsServoGun = true;
            else
                this._isValidationModified = true;
        }

        private void UpdateDeviceGunWithLoops(
          ITxDevice device,
          CApExportToRTRRobotToolData mountedToolData)
        {
            TxObjectList drivingJoints = device.DrivingJoints;
            if (!device.AllJointsAfterCompilation.ToList<ITxObject>().Exists((Predicate<ITxObject>)(x => !(x as TxJoint).IsDependent && !drivingJoints.Contains(x))))
                return;
            this._isValidationModified = mountedToolData.IsGunWithLoops = true;
        }

        private void UpdateDeviceGunWithAvailableKinemtaicFunctions(
          ITxDevice device,
          CApExportToRTRRobotToolData mountedToolData)
        {
            bool flag1 = this.AreKinematicFunctionsAvailable(device);
            bool? nullable1 = (device is ITxStorable txStorable ? txStorable.StorageObject : (TxStorage)null) is TxLibraryStorage storageObject ? new bool?(storageObject.HasDetailedRepresentation) : new bool?();
            if (!flag1)
            {
                bool? nullable2 = nullable1;
                bool flag2 = true;
                if (!(nullable2.GetValueOrDefault() == flag2 & nullable2.HasValue))
                {
                    this._isValidationModified = true;
                    return;
                }
            }
            mountedToolData.IsGunWithAvailableKinematicFunctions = true;
            mountedToolData.ShouldLoadDetailed = !flag1;
        }

        private bool AreKinematicFunctionsAvailable(ITxDevice device)
        {
            bool flag = true;
            if (device.AllJointsAfterCompilation.ToList<ITxObject>().Exists((Predicate<ITxObject>)(x => (x as TxJoint).IsDependent)))
            {
                foreach (ITxObject txObject in (Collection<ITxObject>)device.AllJointsAfterCompilation)
                {
                    if ((txObject as TxJoint).IsDependent)
                    {
                        try
                        {
                            string kinematicsFunction = (txObject as TxJoint).KinematicsFunction;
                        }
                        catch (Exception ex)
                        {
                            flag = false;
                            break;
                        }
                    }
                }
            }
            return flag;
        }

        private void UpdateDeviceGunWithSoftLimits(
          ITxDevice device,
          CApExportToRTRRobotToolData mountedToolData)
        {
            if (!device.AllJointsAfterCompilation.ToList<ITxObject>().Exists((Predicate<ITxObject>)(x => (x as TxJoint).IsDependent)))
                return;
            foreach (TxJoint drivingJoint in (Collection<ITxObject>)device.DrivingJoints)
            {
                if (drivingJoint.HardLimitsData.HardLimitsType == TxJointHardLimitsData.TxJointHardLimitsType.NoHardLimits)
                {
                    bool isRevoluteJoint = drivingJoint.Type == TxJoint.TxJointType.Revolute;
                    if (TxJointJogUtilities.IsNoLimitValue(drivingJoint.LowerSoftLimit, isRevoluteJoint) || TxJointJogUtilities.IsNoLimitValue(drivingJoint.UpperSoftLimit, isRevoluteJoint))
                    {
                        mountedToolData.IsGunWithLimits = false;
                        this._isValidationModified = true;
                        break;
                    }
                }
            }
        }

        private void UpdateRobotExternalAxesDevices(ITxRobot robot, CApExportToRTRRobotData robotData)
        {
            foreach (ITxDevice externalAx in robotData.ExternalAxes)
            {
                CApExportToRTRRobotToolData rtrRobotToolData;
                if (this.DataOfTools.TryGetValue(externalAx, out rtrRobotToolData))
                {
                    if (!rtrRobotToolData.IsServoGun && rtrRobotToolData.IsGunWithLoops && !rtrRobotToolData.IsGunWithAvailableKinematicFunctions && !rtrRobotToolData.IsGunWithLimits)
                    {
                        robotData.HasUnSupportedExternalAxes = true;
                        this._isValidationModified = true;
                    }
                }
                else
                {
                    if (CApExportToRTRUtils.IsVisibleAndHaveApprox(externalAx as ITxDisplayableObject))
                    {
                        this.UpdateRobotToolData(externalAx, robotData, robot);
                        this.DataOfTools[externalAx].IsMountedTool = false;
                    }
                    this._isValidationModified = true;
                }
            }
        }

        public void UpdateRobots()
        {
            foreach (ITxObject selectedObject in (Collection<ITxObject>)this.SelectedObjects)
            {
                if (!(selectedObject is ITxObjectCollection objectCollection))
                    TxEngineeringDataInternal.WriteInfoMessageToLog("Encountered an object which is a non ITxObjectCollection - Please see if there is a need to add a fitter for some unsupported object in CApExportToRTRBaseValidator");
                else if (!(selectedObject is ITxLogicalCollection) && !(selectedObject is ITxLogicalGroup))
                {
                    TxObjectList txObjectList;
                    if (!(selectedObject is ITxRobot))
                    {
                        txObjectList = objectCollection.GetAllDescendants((ITxTypeFilter)new TxTypeFilter(typeof(ITxRobot)));
                    }
                    else
                    {
                        txObjectList = new TxObjectList();
                        txObjectList.Add(selectedObject);
                    }
                    foreach (ITxRobot txRobot in (Collection<ITxObject>)txObjectList)
                    {
                        ITxRobot robot = txRobot;
                        this._dispatcher.BeginInvoke((Action)(() =>
                        {
                            if (!CApExportToRTRUtils.IsVisibleAndHaveApprox(robot as ITxDisplayableObject))
                                return;
                            this.ComputeRobotData(robot);
                        }), DispatcherPriority.Background);
                    }
                }
            }
        }

        internal void Update3DData()
        {
            this._dispatcher.BeginInvoke((Action)(() => new CUiExportToRTRContent3DObjectDataGenerator(this).Execute()), DispatcherPriority.Background);
        }

        internal void UpdateCollisionSets()
        {
            this._dispatcher.BeginInvoke((Action)(() => new CUiExportToRTRContentAllRobotsCollisionSetsDataGenerator(this).Execute()), DispatcherPriority.Background);
        }

        private Dictionary<ITxObject, TxRobot> Compute3DMapOfRobots()
        {
            Dictionary<ITxObject, TxRobot> ret3DMapOfRobots = new Dictionary<ITxObject, TxRobot>();
            foreach (KeyValuePair<TxRobot, List<ITxObject>> keyValuePair in this.RTR3DData.RobotObjectsToExport)
            {
                TxRobot key = keyValuePair.Key;
                foreach (ITxObject txObject in keyValuePair.Value)
                    this.Compute3DMapOfRobotAndObjects(keyValuePair.Key, txObject, ret3DMapOfRobots);
            }
            return ret3DMapOfRobots;
        }

        private void Compute3DMapOfRobotAndObjects(
          TxRobot robot,
          ITxObject obj,
          Dictionary<ITxObject, TxRobot> ret3DMapOfRobots)
        {
            ret3DMapOfRobots.Add(obj, robot);
            CApExportToRTR3DData.ObjectExport3DData objectExport3Ddata;
            if (!this.RTR3DData.ObjectWithSubObjectToExport.TryGetValue(obj, out objectExport3Ddata))
                return;
            foreach (ITxObject txObject in objectExport3Ddata.SeparateFromParent3D)
                this.Compute3DMapOfRobotAndObjects(robot, txObject, ret3DMapOfRobots);
        }

        internal enum ConnectionWizardType
        {
            None,
            ApproachAndRetract,
            Approach,
        }
    }
}
